#ifndef bits_h
#define bits_h

// this header needs
#include "../wchar/string/string.h"
//^ to continue with the owl_type enum chain

// I assume this
#define OWL_BYTE_BITS 8

// enum with bit shifting modes
typedef enum
{
  OWL_BITSHIFT_RIGHT,
  OWL_BITSHIFT_LEFT,
} owl_bitshift_dir;

// bit array
typedef struct
{
  owl_bytarr * arr;
  owl_umax left_pad;
  owl_umax num_bits;
} owl_bitarr;

typedef enum {
  OWL_TYPE_BITSHIFT_DIR = OWL_TYPE_STR + 1,
  OWL_TYPE_BITARR,
} owl_type_bits_h;

// basic functions
owl_bool owl_check_bitarr_pointer(owl_byte * src, owl_umax size);
owl_bool owl_check_bitarr_members(owl_byte * ptr, owl_umax size, owl_umax left_pad, owl_umax num_bits);
owl_bool owl_check_bitarr_all(owl_bitarr * data, owl_umax size);
owl_bitarr * owl_create_bitarr(owl_byte * data, owl_umax size, owl_umax left_pad, owl_umax num_bits);
owl_umax owl_free_bitarr(owl_bitarr * bits);
owl_umax owl_print_bitarr(owl_byte * src, owl_umax size);
owl_char owl_comp_bitarr(owl_byte * bits1, owl_byte * bits2);

// specific functions
owl_bool owl_check_bitshift_dir(owl_bitshift_dir shift); // internal use
struct owl_bitarr_extra_vars {
  owl_umax first_byte_pos, last_byte_pos; 
  owl_byte first_byte_mask, last_byte_mask,
           first_bit_offset, last_bit_offset;
} owl_get_bitarr_extra_vars(owl_bitarr * bits); // internal use
owl_umax owl_bitshift(owl_bitarr * bits, owl_bitshift_dir shift);
owl_umax owl_n_bitshift(owl_bitarr * bits, owl_bitshift_dir shift, owl_umax n);
owl_umax owl_circ_bitshift(owl_bitarr * bits, owl_bitshift_dir shift);
owl_umax owl_n_circ_bitshift(owl_bitarr * bits, owl_bitshift_dir shift, owl_umax n);
owl_umax owl_clear_bitarr(owl_bitarr * bits, owl_byte zero_or_one);
owl_bitarr * owl_get_bits(owl_bitarr * src, owl_umax left_pad_offset, owl_umax new_num_bits);
owl_bitarr * owl_normalize_bitarr(owl_bitarr * bits);
owl_bool owl_write_bits(owl_bitarr * src, owl_bitarr * dest);

#include "bits.c"

#endif // bits_h
